package eu.smoothit.sis.metering.impl;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import org.apache.log4j.Logger;

import eu.smoothit.sis.db.SisDAOFactory;
import eu.smoothit.sis.db.api.daos.IComponentConfigDAO;
import eu.smoothit.sis.db.impl.entities.ComponentConfigEntry;
import eu.smoothit.sis.metering.Metering;
import eu.smoothit.sis.metering.MeteringTimer;

@Stateless
public class MeteringTimerImpl implements MeteringTimer {
	
	private @Resource TimerService ts;

	private static Logger logger = Logger.getLogger(MeteringTimerImpl.class.getName());
	
	@Override
	@TransactionAttribute(TransactionAttributeType.SUPPORTS)
	public void startTimer() {

		//try {
		//Thread.sleep(60000);
		//} catch (Exception e) {}

		for(Object o : ts.getTimers())
			if (((Timer) o).getInfo().toString().equals("MeteringTimer"))
				((Timer)o).cancel();

		// Get the refresh rate from the DB
		IComponentConfigDAO dao = SisDAOFactory.getFactory().createComponentConfigDAO();
		long updateIntervall = Metering.DEFAULT_UPDATE_INTERVALL;
		
		ComponentConfigEntry config = dao.findByComponentAndName(Metering.COMPONENT_NAME, Metering.METERING_PROP_REFRESH_RATE);
		if(config == null || config.getValue() == null) {
			logger.warn(Metering.METERING_PROP_REFRESH_RATE + " not found in SIS DB. Using default values.");
		} else {
			if(config.getValue() instanceof Integer) {
				updateIntervall = (Integer)config.getValue();
	    		logger.info(Metering.METERING_PROP_REFRESH_RATE + " = " + updateIntervall + "s");
			} else if(config.getValue() instanceof String) {
				logger.warn(Metering.METERING_PROP_REFRESH_RATE + " is a String");
				String tmp = (String)config.getValue();
				try {
					updateIntervall = Integer.valueOf(tmp);
					logger.info(Metering.METERING_PROP_REFRESH_RATE + " = " + updateIntervall + "s");    							
				} catch(Exception ex) {
		        	logger.error("Invalid refresh rate: " + ex.getMessage());
				}
			} else {
				logger.error(Metering.METERING_PROP_REFRESH_RATE + " is not an Integer");
			}
			
			if(updateIntervall < Metering.MIN_UPDATE_INTERVALL) {
				updateIntervall = Metering.MIN_UPDATE_INTERVALL;
				logger.warn(Metering.METERING_PROP_REFRESH_RATE + " is smaller than " + Metering.MIN_UPDATE_INTERVALL + "s. Setting the refresh rate to " + updateIntervall + "s.");
			}
		}
		
    	updateIntervall *= 1000; // convert to milliseconds
		ts.createTimer(updateIntervall, updateIntervall, "MeteringTimer");
		logger.info("MeteringTimer started.");
	}
	
	@Override
	public void stopTimer() {		
		for(Object o : ts.getTimers())
			if (((Timer) o).getInfo().toString().equals("MeteringTimer"))
				((Timer)o).cancel();

		logger.info("MeteringTimer canceled.");
	}

	@Timeout
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void timeoutHandler(Timer timer) {

		if (timer.getInfo().toString().equals("MeteringTimer")){
			logger.info("MeteringTimer expired.");
		
			// Update the Metering
			Metering.getInstance().reloadConfig();
			Metering.getInstance().refresh();
		}
	}

}
